﻿using House.Server.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace House.Server.Service
{
    public abstract class BaseService<U, T>
        where U : GenericBaseRepository<T>, new()
        where T : class
    {
        /// <summary>
        /// 需要通过工厂创建的DAL对象
        /// </summary>
        protected U Dal
        {
            get { return new U(); }
        }

        #region 通用查询

        /// <summary>
        /// 插入数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <returns></returns>
        public bool Insert(T obj)
        {
            return Dal.Insert(obj);
        }

        /// <summary>
        /// 插入数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <param name="index">最后插入ID</param>
        /// <returns></returns>
        public bool Insert(T obj, out long index)
        {
            return Dal.Insert(obj, out index);
        }

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="dtos">批量对象</param>
        /// <returns></returns>
        public bool InsertAll(IEnumerable<T> dtos)
        {
            return Dal.InsertAll(dtos);
        }

        /// <summary>
        /// 修改数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <returns></returns>
        public bool Update(T obj)
        {
            return Dal.Update(obj);
        }
        /// <summary>
        /// 修改数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <param name="Where">Labmda条件</param>
        /// <returns></returns>
        public bool Update(T obj, Expression<Func<T, bool>> Where)
        {
            return Dal.Update(obj, Where);
        }
        /// <summary>
        /// 修改数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <param name="onlyFields">Labmda指定字段</param>
        /// <returns></returns>
        public bool UpdateOnly(T obj, Expression<Func<T, object>> onlyFields)
        {
            return Dal.UpdateOnly(obj, onlyFields);
        }

        /// <summary>
        /// 修改数据（通用方法）
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="obj">实例</param>
        /// <param name="onlyFields">Labmda指定字段</param>
        ///<param name="Where">Labmda条件</param>
        /// <returns></returns>
        public bool UpdateOnly(T obj, Expression<Func<T, object>> onlyFields, Expression<Func<T, bool>> Where)
        {
            return Dal.UpdateOnly(obj, onlyFields, Where);
        }

        /// <summary>
        ///查询（通用方法）
        /// </summary>
        /// <returns></returns>
        public List<T> Select()
        {

            return Dal.Select();
        }
        /// <summary>
        ///查询（通用方法）
        /// </summary>
        /// <param name="predicate">Labmda条件</param>
        /// <returns></returns>
        public List<T> Select(Expression<Func<T, bool>> predicate)
        {
            return Dal.Select(predicate);
        }

        /// <summary>
        /// 通用分页查询
        /// </summary>
        /// <param name="pageIndex">页序号（从1开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <returns></returns>
        public List<T> SelectByPager(int pageIndex, int pageSize, out long totalSize)
        {
            return Dal.SelectByPager(pageIndex, pageSize, out totalSize);
        }

        /// <summary>
        /// 通用分页查询
        /// </summary>
        /// <param name="Where">条件</param>
        /// <param name="pageIndex">页序号（从1开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <returns></returns>
        public List<T> SelectByPager(Expression<Func<T, bool>> Where, int pageIndex, int pageSize, out long totalSize)
        {
            return Dal.SelectByPager(Where, pageIndex, pageSize, out totalSize);
        }

        /// <summary>
        /// 通用分页查询
        /// </summary>
        /// <param name="pageIndex">页序号（从1开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <returns></returns>
        public List<T> SelectByPagerDesc(Expression<Func<T, object>> Desc, int pageIndex, int pageSize, out long totalSize)
        {
            return Dal.SelectByPagerDesc(Desc, pageIndex, pageSize, out totalSize);
        }

        /// <summary>
        /// 通用分页查询
        /// </summary>
        /// <param name="Where">条件</param>
        /// <param name="pageIndex">页序号（从1开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <returns></returns>
        public List<T> SelectByPagerDesc(Expression<Func<T, bool>> Where, Expression<Func<T, object>> Desc, int pageIndex, int pageSize, out long totalSize)
        {
            return Dal.SelectByPagerDesc(Where, Desc, pageIndex, pageSize, out totalSize);
        }

        /// <summary>
        /// 查询多条数据 类似in
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns></returns>
        public List<T> SelectByIds(System.Collections.IEnumerable ids)
        {
            return Dal.SelectByIds(ids);
        }

        /// <summary>
        /// 查询单条数据 通过主键查询
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns></returns>
        public T SelectById(int id)
        {
            return Dal.SelectById(id);
        }

        /// <summary>
        /// 删除数据（通用方法）
        /// </summary>
        /// <param name="id">主键删除</param>
        /// <returns></returns>
        public bool DeleteById(int id)
        {
            return Dal.DeleteById(id);
        }

        /// <summary>
        /// 删除数据（通用方法）
        /// </summary>
        /// <param name="id">主键删除</param>
        /// <param name="Where">Labmda条件</param>
        /// <returns></returns>
        public bool Delete(Expression<Func<T, bool>> Where)
        {
            return Dal.Delete(Where);
        }

        #endregion
    }
}
